//
// Created by Dinger on 2021/10/2.
//

#ifndef FUNDAMENTALS_OF_COMPILING_SEMANTIC_ANALYSIS_H
#define FUNDAMENTALS_OF_COMPILING_SEMANTIC_ANALYSIS_H

#include"stdafx.h"
#include"syntactic_analysis.h"
#include"semantic_form.h"

using namespace std;

class SemanticAnalyzer {
private:
    Tree _analyseTree;
    ItemForm _itemForm;
    string _beginString;
    vector<QuaternaryFormula> _quaternaryFormulas;
    bool _labelFlag;
    string _labelName;
    int _temporaryVariableNumber;
    int _labelNumber;
    bool _isRight;
    vector<string> _errorStrings;
    set<string> _errorSymbolNames;

    void makeItemForm(Tree *tree);

    void dealWithDefine(vector<Tree *> trees, Tree *tree);

    void dealWithAssignment(vector<Tree *> trees, Tree *tree);

    vector<string> makeAnswerVector_assignment(Tree *tree, bool &isNumbers, stack<string> &arithmeticStack,
                                               string name);

    void findAnswerVector_assignment(vector<string> &answerVector, Tree *tree, bool &isNumbers,
                                     stack<string> &arithmeticStack);

    int answerString2answer_assignment(string answerString, bool &isNumbers);

    int priority_assignment(string opt);

    void calculate_assignment(stack<int> &opdstack, string opt);

    int calculateExpression_assignment(vector<string> vec);

    void insertQuaternaryFormulas(stack<string> &arithmeticStack);

    void insertQuaternaryFormulas_arithmetic(stack<string> &arithmeticStack);

    void insertQuaternaryFormulas_assignment(stack<string> &arithmeticStack);

    void dealWithConditional(vector<Tree *> trees, Tree *tree);

    void dealWithRelational(vector<Tree *> trees, Tree *tree, string &labelName1, string &labelName2, bool isWhile);

    void dealWithWhile(vector<Tree *> trees, Tree *tree);



    string makeErrorString(int row,int col, string errorString);

public:
    SemanticAnalyzer();

    SemanticAnalyzer(Tree analyseTree, string beginString);

    bool getIsRight() {
        return _isRight;
    }

    void outputErrorStrings();

    void writeFormulaInFile(string fileName);
};

#endif //FUNDAMENTALS_OF_COMPILING_SEMANTIC_ANALYSIS_H
